#ifndef COMPLEX_H
#define COMPLEX_H

#include <iostream>
#include <sstream>

class Complex {
public:
    Complex(double real, double imag) : real(real), imag(imag) {}

    Complex operator+(const Complex& other) const {
        return Complex(real + other.real, imag + other.imag);
    }

    Complex operator-(const Complex& other) const {
        return Complex(real - other.real, imag - other.imag);
    }
    
    Complex operator*(const Complex& other) const {
        return Complex(real * other.real - imag * other.imag, real * other.imag + imag * other.real);
    }
    
    Complex operator/(const Complex& other) const {
        double denom = other.real * other.real + other.imag * other.imag;
        if(denom == 0)
            throw std::invalid_argument("Denominator is zero!");
        return Complex((real * other.real + imag * other.imag) / denom, (imag * other.real - real * other.imag) / denom);
    }
    
    void print() const{
        std::cout << real << " + " << imag << "i" << std::endl;
    }
    
    friend std::ostream & operator<<(std::ostream &os, const Complex& c)
    {
        if(c.real == 0 && c.imag == 0)
            return os << "0";
    
        if(c.real)
            os << c.real;
    
        if(c.imag < 0)
            os << c.imag << "i";
        else if(c.imag > 0)
            os << "+" << c.imag << "i";
    
        return os;
    }

private:
    double real;
    double imag;
};

#endif
